#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "response.h"

#define ECHO_PORT 9999
#define BUF_SIZE 4096

int close_socket(int sock){
    if (close(sock)){
        fprintf(stderr, "Failed closing socket.\n");
        return 1;
    }
    return 0;
}

void process_pipelined_request(int client_sock, char *recv_buf){
    char *request_head, *request_tail, *request_cpy;
    int request_size;
    request_head = recv_buf;    // request_head首地址 = recv_buf首地址

    while((request_tail = strstr(request_head, "\r\n\r\n")) != NULL){   // 查找字符串\r\n\r\n第一次出现的位置
        request_tail += 4;
        request_size = request_tail - request_head;                 // 计算request的长度
        request_cpy = (char *)malloc(request_size * sizeof(char));      // 将单个request拷贝出来
        memset(request_cpy, '\0', request_size);
        strncpy(request_cpy, request_head, request_size);

        printf("----- Received -----\n%s\n",request_cpy);

        handle_request(client_sock, request_size, request_cpy);         // 处理单个request
        free(request_cpy);                                              // 释放request_cpy
        request_head = request_tail;                                // 将request_head定位到下一个请求开始的地方
    }
}

int main(int argc, char* argv[]){
    int sock, client_sock;
    ssize_t readret;
    socklen_t cli_size;
    struct sockaddr_in addr, cli_addr;
    char recv_buf[BUF_SIZE];

    fprintf(stdout, "----- Echo Server -----\n");
    
    // 创建socket
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1){    
        fprintf(stderr, "Failed creating socket.\n");
        return EXIT_FAILURE;
    }

    addr.sin_family = AF_INET;          // IPv4
    addr.sin_port = htons(ECHO_PORT);   // port
    addr.sin_addr.s_addr = INADDR_ANY;  // ip = 0.0.0.0 (本机)

    // 绑定socket
    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr))){
        close_socket(sock);
        fprintf(stderr, "Failed binding socket.\n");
        return EXIT_FAILURE;
    }

    // 监听socket，允许连入5个客户端
    if (listen(sock, 5)){
        close_socket(sock);
        fprintf(stderr, "Error listening on socket.\n");
        return EXIT_FAILURE;
    }

    // 接收客户端的数据并回显
    while (1){
        // accept客户端 并打印客户端信息
        cli_size = sizeof(cli_addr);
        if ((client_sock = accept(sock, (struct sockaddr *) &cli_addr, &cli_size)) == -1){
            close(sock);
            fprintf(stderr, "Error accepting connection.\n");
            return EXIT_FAILURE;
        }

        getpeername(client_sock, (struct sockaddr *)&cli_addr, &cli_size); 
        printf("Accept new connection from %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
       
        // 接收客户端的数据并回显 
        // 这里之后应该还要改，改成接收完所有数据再处理，不然可能会把数据部分当成了头部来处理
        // 目前只能处理短数据
        readret = 0;
        while((readret = recv(client_sock, recv_buf, BUF_SIZE, 0)) >= 1){ // 接收
            handle_request(client_sock, readret, recv_buf);
            memset(recv_buf, 0, BUF_SIZE);
        } 

        if (readret == -1){
            close_socket(client_sock);
            close_socket(sock);
            fprintf(stderr, "Error reading from client socket.\n");
            return EXIT_FAILURE;
        }

        if (close_socket(client_sock)){
            close_socket(sock);
            fprintf(stderr, "Error closing client socket.\n");
            return EXIT_FAILURE;
        }
    }

    close_socket(sock);
    return EXIT_SUCCESS;
}
